package com.walkline.util.ui;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.system.KeypadListener;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.TouchEvent;
import net.rim.device.api.ui.XYRect;
import net.rim.device.api.ui.component.BitmapField;

public class ScrollableImageField extends BitmapField
{
    private Bitmap _theImage;
    private int _preferredHeight;
    private int _preferredWidth;

    private int _xCoord = 0;
    private int _yCoord = 0;

    private int _xTouch = 0;
    private int _yTouch = 0;

    public ScrollableImageField(Bitmap theImage) 
    {    
        super(theImage, BitmapField.FOCUSABLE | BitmapField.FIELD_VCENTER | BitmapField.FIELD_HCENTER);

        _theImage = theImage;

        calculateSize();
    }
    
    public ScrollableImageField(EncodedImage theImage) {this(theImage.getBitmap());}

    private void calculateSize()
    {
    	_preferredHeight=_theImage.getHeight() > Display.getHeight() ? Display.getHeight() : _theImage.getHeight();  
    	_preferredWidth=_theImage.getWidth() > Display.getWidth() ? Display.getWidth() : _theImage.getWidth();
    }

    public void setBitmap(Bitmap bitmap)
    {
        super.setBitmap(bitmap);
        //updateLayout();

        _xCoord = 0;
        _yCoord = 0;

        _theImage = bitmap;
        calculateSize();

        updateLayout();
    }

    public void setImage(EncodedImage image)
    {
        _theImage = image.getBitmap();

        _xCoord = 0;
        _yCoord = 0;

        this.setBitmap(_theImage);
        //calculateSize();
    }

    public int getPreferredHeight() {return _preferredHeight;}

    public int getPreferredWidth() {return _preferredWidth;}

    protected void paint(Graphics graphics)
    {
        XYRect rect = this.getManager().getContentRect();        

        graphics.drawBitmap(0, 0, rect.width, rect.height, _theImage, _xCoord, _yCoord);
    }

    protected void drawFocus(Graphics graphics, boolean on) {}

    protected boolean navigationMovement(int dx, int dy, int status, int time)
    {
        if((status & KeypadListener.STATUS_ALT) != 0) {return super.navigationMovement(dx, dy, status, time);}

        if (scrollImage(dx * 10, dy * 10)) {return true;}

        return super.navigationMovement(dx, dy, status, time);
    }

    protected boolean touchEvent(TouchEvent touchEvent)
    {
    	int event = touchEvent.getEvent();

    	if (event == TouchEvent.DOWN && touchEvent.isValid())
    	{
    		_xTouch = touchEvent.getX(1);
			_yTouch = touchEvent.getY(1);
    	} else if (event == TouchEvent.MOVE && touchEvent.isValid()) {
			boolean result = scrollImage((touchEvent.getX(1) - _xTouch), (touchEvent.getY(1) - _yTouch));

			_xTouch = touchEvent.getX(1);
			_yTouch = touchEvent.getY(1);

			return result;
    	}

    	return false;
    }

    private boolean scrollImage(int xScroll, int yScroll)
    {
        XYRect rect = getContentRect();

        if (rect.width < _theImage.getWidth() || rect.height < _theImage.getHeight())
        {
            _xCoord -= xScroll;
            _yCoord -= yScroll;

            //If the user has scrolled to the end of the image, use the default
            //navigationMovement to allow focus to scroll off the field.
            if (_xCoord < 0  || _yCoord < 0  || ((_theImage.getWidth() - _xCoord) < rect.width) || ((_theImage.getHeight() - _yCoord) < rect.height))
            {
                //Ensure the coordinates do not go lower than 0.
                if (_xCoord < 0) {_xCoord = 0;}
                if (_yCoord < 0) {_yCoord = 0;}

                //Ensure that we don't scroll beyond the image size (causing white space to be drawn).
                if ((_theImage.getWidth() - _xCoord) < rect.width)
                {
                    _xCoord = _theImage.getWidth() - rect.width;
                    if (_xCoord < 0) {_xCoord = 0;}
                }

                if ((_theImage.getHeight() - _yCoord) < rect.height)
                {
                    _yCoord = _theImage.getHeight() - rect.height;
                    if (_yCoord < 0) {_yCoord = 0;}
                }
                //Scrolling is not required.
                return false;
            } else {
                //The image was scrolled and the movement consumed.
                //Redraw the bitmap.
                this.invalidate();
                return true;
            }
        } else
        {
            //Scrolling is not required.
            return false;
        }    	
    }
} 